package darknet.core.impl.net;

import darknet.core.spec.friend.FriendManager;
import darknet.application.base.spec.BaseApplication;
import darknet.core.spec.net.NetworkManager;
import darknet.core.spec.net.Node;
import darknet.core.spec.net.NodeState;
import java.io.IOException;
import java.util.TimerTask;

/**
 * Thread pinging all nodes known.
 * Useful to keep to date the online and offline list of nodes.
 *
 * @author Yoyo
 */
class PingerTimerTask extends TimerTask {

    /** The friend manager */
    private FriendManager friendManager;

    /** The network Manager */
    private NetworkManager networkManager;

    /** The base application */
    private BaseApplication baseApplication;

    /**
     * Initialise a new Pinger timer task.
     *
     * @param friendManager
     * @param networkManager
     * @param baseApplication
     */
    PingerTimerTask(FriendManager friendManager,
            NetworkManager networkManager,
            BaseApplication baseApplication) {

        if (friendManager == null) {
            throw new IllegalArgumentException("friendManager is null");
        }
        this.friendManager = friendManager;

        if (networkManager == null) {
            throw new IllegalArgumentException("networkManager is null");
        }
        this.networkManager = networkManager;

        if (baseApplication == null) {
            throw new IllegalArgumentException("baseApplication is null");
        }
        this.baseApplication = baseApplication;
    }

    @Override
    public void run() {

        for (String friendName : friendManager.get()) {
            
            Node nodeInfo = networkManager.getNode(friendName);
            NodeImpl nodeUpdate = new NodeImpl(
                        nodeInfo.getName(), nodeInfo.getAddress(),
                        nodeInfo.getPort(), NodeState.OFFLINE);

            try {

                baseApplication.ping(friendName);
                nodeUpdate.setState(NodeState.ONLINE);
                System.out.println(friendName + " is ONLINE");

            } catch (IOException ex) {
                nodeUpdate.setState(NodeState.OFFLINE);
                System.out.println(friendName + " is OFFLINE");
            }

            networkManager.update(nodeUpdate);
        }
    }
}
